package terrain;

import test.Constants;

import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;

public class TileTerrain {
	private Node tileNode;
	
	private TileTerrain tileUp = null;
	private TileTerrain tileDown = null;
	private TileTerrain tileLeft = null;
	private TileTerrain tileRight = null;
	
	private TopDown topDown;
	private Wall wall;
	
	private int type;
	private Vector3f pos;
	private Geometry top;
	private Geometry down;
	private Geometry north;
	private Geometry south;
	private Geometry west;
	private Geometry east;
	
	public TileTerrain(Node tileNode, int type, int x, int y, TopDown topDown, Wall wall) {
		this.tileNode = tileNode;
		this.topDown = topDown;
		this.wall = wall;
		this.type = type;
		pos = new Vector3f(x, y, 0);
	}
	
	public void generate() {
		if (Constants.TOP == Constants.type(type)) {
			this.top = topDown.getTop(type);
			locateAndAdd(this.top);
		} else if (Constants.DOWN == Constants.type(type)) {
			this.down = topDown.getDown(type);
			locateAndAdd(this.down);
					    
			if(tileLeft != null) {
				if (Constants.TOP == Constants.type(tileLeft.getType())) {
					this.west = wall.getSide(Constants.WEST, tileLeft.getType());
					locateAndAdd(this.west);
				}
			}
			if (tileRight != null) {
				if (Constants.TOP == Constants.type(tileRight.getType())) {
					this.east = wall.getSide(Constants.EAST, tileRight.getType());
					locateAndAdd(this.east);
				}
			}
			if (tileUp != null) {
				if (Constants.TOP == Constants.type(tileUp.getType())) {
					this.north = wall.getSide(Constants.NORTH, tileUp.getType());
					locateAndAdd(this.north);
				}
			}
			if (tileDown != null) {
				if (Constants.TOP == Constants.type(tileDown.getType())) {
					this.south = wall.getSide(Constants.SOUTH, tileDown.getType());
					locateAndAdd(this.south);
				}
			}
		}
	}
	
	public void fixNeighbor() {
		if (tileUp != null) {
			if (Constants.type(tileUp.getType()) == Constants.DOWN) {
				tileUp.setSouth(null);
			} else {
				this.north = wall.getSide(Constants.NORTH, tileUp.getType());
				locateAndAdd(this.north);
			}
		}
		if (tileDown != null) {
			if (Constants.type(tileDown.getType()) == Constants.DOWN) {
				tileDown.setNorth(null);
			} else {
				this.south = wall.getSide(Constants.SOUTH, tileDown.getType());
				locateAndAdd(this.south);
			}
		}
		if (tileLeft != null) {
			if (Constants.type(tileLeft.getType()) == Constants.DOWN) {
				tileLeft.setEast(null);
			} else {
				this.west = wall.getSide(Constants.WEST, tileLeft.getType());
				locateAndAdd(this.west);
			}
		}
		if (tileRight != null) {
			if (Constants.type(tileRight.getType()) == Constants.DOWN) {
				tileRight.setWest(null);
			} else {
				this.east = wall.getSide(Constants.EAST, tileRight.getType());
				locateAndAdd(this.east);
			}
		}
	}
	
	public void setTileUp(TileTerrain tileUp) {
		this.tileUp = tileUp;
	}

	public void setTileDown(TileTerrain tileDown) {
		this.tileDown = tileDown;
	}

	public void setTileLeft(TileTerrain tileLeft) {
		this.tileLeft = tileLeft;
	}

	public void setTileRight(TileTerrain tileRight) {
		this.tileRight = tileRight;
	}
	
	private void locateAndAdd(Geometry n) {
		n.move(pos);
				
		tileNode.attachChild(n);
		
		if (n.getName().equals("Earth")) {
		    /** Must add a light to make the lit object visible! */
		    DirectionalLight sun = new DirectionalLight();
		    sun.setDirection(new Vector3f(0,0,-2).normalizeLocal());
		    sun.setColor(ColorRGBA.White);
		    tileNode.addLight(sun);
		}
	}

	public int getType() {
		return type;
	}
	
	public Vector3f getPos() {
		return pos;
	}

	public Geometry getTop() {
		return top;
	}

	public void setTop(Geometry top) {
		if (this.top != null) {
			tileNode.detachChild(this.top);
			this.top = null;
		}
		if (top == null) {
			this.down = topDown.getDown(Constants.MUD);
			this.type = Constants.MUD;
			locateAndAdd(this.down);
			fixNeighbor();
		} else {
			this.top = top;
			locateAndAdd(this.top);
		}
	}

	public void setDown(Geometry down) {
		this.down = down;
		locateAndAdd(this.down);
	}

	public void setNorth(Geometry north) {
		if (this.north != null) {
			tileNode.detachChild(this.north);
			this.north = null;
		}
		if (north != null) {
			this.north = north;
			locateAndAdd(this.north);
		}
	}

	public void setSouth(Geometry south) {
		if (this.south != null) {
			tileNode.detachChild(this.south);
			this.south = null;
		}
		if (south != null) {
			this.south = south;
			locateAndAdd(this.south);
		}
	}

	public void setWest(Geometry west) {
		if (this.west != null) {
			tileNode.detachChild(this.west);
			this.west = null;
		}
		if (west != null) {
			this.west = west;
			locateAndAdd(this.west);
		}
	}

	public void setEast(Geometry east) {
		if (this.east != null) {
			tileNode.detachChild(this.east);
			this.east = null;
		}
		if (east != null) {
			this.east = east;
			locateAndAdd(this.east);
		}
	}
}
